import re
from time import sleep

from selenium.webdriver.common.by import By

from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger
from qturboframe.public_ui.jresui2.checkbox import CheckBox

from .base_element import BaseElement


class QuoteTable(BaseElement):
    """
    table表格操作 - table的表头和表身在不同的table中

    :Attributes:
     - _driver: 控件所在的当前webdriver对象
     - _element: 控件元素webelement对象
     - timeout: 步骤操作的超时时间

    :Raises:
        当element_para类型错误时则抛出AttributeError异常

    :Example:
     - 例1: Table(webelement)
     - 例2: Table({By.CLASS_NAME:'class_name','text':'文本信息'})
     - 例3: Table({By.CLASS_NAME:'class_name','text':'文本信息'}, father=driver)
     - 例4: Table({By.CLASS_NAME:'class_name','text':'文本信息'}, father=webelement)
    """

    def __init__(self, element_para, father=None, timeout=5):
        super().__init__(element_para, father, timeout)
        self.table_list = []
        #table的表头和表身在不同的table中
        for element in self._elements:
            if element.is_displayed() and BaseElement(element).get_text().strip()!='':
                self.table_list.append(element)
        if len(self.table_list) == 2:
            self.header_table = self.table_list[0]
            self.body_table = self.table_list[1]
        else:
            raise SeleniumError("本页面上table的个数为{},本类只支持table的表头和表身在不同的table中的情况".format(len(self.table_list)))

    def get_table_row(self, header_content:dict):
        '''
        Jres2.0 根据列名和列名信息查找jres2.0的表格中所在的行数,字典key为table为列名，字典值为table为内容，
        此方法只支持单列内容查找

        :Args:
         - header_content: {"补充确认书编号","TestCompArchiveNo1016"}

        :Returns:
            返回查找的某一行所有元素,类型为List<WebElement>

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: select.get_table_row({"补充确认书编号","TestCompArchiveNo1016"})
        '''
        query_header_index = None
        query_content = None
        table_title_list = self.__get_table_titles() #得到table的header

        for key, value in header_content.items():
            query_header_index = table_title_list.index(key)+1 #得到要查找的header在第几列
            query_content = value

        page_no = 1
        while True:
            td_xpath = ".//tbody/tr/td[{}]".format(query_header_index)
            tds = self.body_table.find_elements_by_attribute(By.XPATH, td_xpath, timeout=0.2)
            content_list = self.__get_tds_text(tds)
            if query_content in content_list:
                # 当查找到要查找的内容或者table已经被翻到最后一页则跳出
                break
            else:
                page_no += 1
        try:
            row_index = content_list.index(query_content) + 1
            logger.debug("查找的元素在第{}页，第{}行".format(page_no, row_index))

            #得到要查找内容的整行元素，类型为List<WebElement>
            row_xpath = ".//tbody/tr[{}]/td".format(row_index)
            row_element = self.body_table.find_elements_by_attribute(By.XPATH, row_xpath, timeout=0.2)
        except:
            raise SeleniumError("没有找到包含'{}'的行".format(query_content))
        return row_element

    def get_table_one_cell(self, header_content:dict, cell_title):
        '''
        Jres2.0 根据列名和列名信息查找jres2.0的表格中所在的行数,字典key为table为列名，字典值为table为内容，
        此方法只支持单列内容查找

        :Args:
         - header_content: {"补充确认书编号","TestCompArchiveNo1016"}
         - cell_title: 要返回的cell的title

        :Returns:
            返回table中某一个cell,返回的类型为WebElement

        :Raises:
            SeleniumError: 表格行数查找失败

        :Example:
         - 例: select.get_table_one_cell({"补充确认书编号","TestCompArchiveNo1016"},"操作")
        '''
        table_title_list = self.__get_table_titles()
        row_element = self.get_table_row(header_content)
        return row_element[table_title_list.index(cell_title)]

    def deal_checkbox_in_table(self, header_content:dict=None, is_all_checked=False):
        #使所有的复选框不被选中
        CheckBox({By.CSS_SELECTOR:"input[type='checkbox']"}, father=self.body_table, timeout=self.timeout).uncheck_all_checkboxes()

        if is_all_checked:
            CheckBox({By.CSS_SELECTOR: "input[type='checkbox']"}, father=self.body_table, timeout=self.timeout).check_all_checkboxes()
        else:
            row = self.get_table_row(header_content)
            #获取到tr标签
            tr = row[0].find_element_by_attribute(By.XPATH,"..", timeout=0.1)
            CheckBox({By.CSS_SELECTOR: "input[type='checkbox']"}, father=tr, timeout=self.timeout).check_all_checkboxes()


    def __get_tds_text(self, tds):
        text_list = []
        for td in tds:
            text_list.append(BaseElement(td).get_text())
        return text_list

    def __get_table_titles(self):
        """
        获取table的header
        """
        #table中有thead标签
        title_td_xpath = ".//tr[1]/td"
        tds = self.header_table.find_elements_by_attribute(By.XPATH, title_td_xpath, timeout=0.1)
        title_list = []
        for td in tds:
            title_list.append(BaseElement(td).get_text().replace("\n","").replace("\t",""))
        return title_list


